#!/usr/bin/env python


import sys
import os
import types
import cPickle as pickle
import base64
import sys

if os.path.exists("../../../"):
    sys.path.append("../../../")
sys.path.append(".")
#print os.curdir
from core.utils.commands_line import CommandsLines

class Builder(CommandsLines):
 
    def __init__(self):
        CommandsLines.__init__(self)
        self._module=None
        self._name=None
        self._child=True
        self._type=None
        self._import=None
        
    def _modules(self,module):
        "return information about modules"
        self._module=module
    
    def _typeinfos(self,type_):
        "return information about type"
        self._type=type_
    
    def _objname(self,name):
        "return information about object"
        self._name=name
    
    def _dir(self,path):
        sys.path.append(path)
        
    
    def _nochild(self):
        self._child=False
    
    def command(self,argv):
        ret = CommandsLines.command(self,argv)
        if not len(argv) or argv[0]=="-h" or argv[0]=="--help" or argv[0]=="help":
            return
        #print ret
        result=base64.b64encode(pickle.dumps(ret))
        sys.stdout.write(result)
            
    def childs(self):
        "return list of child"
        return self.__infos__(self._name,self._module,self._type)
    
    def modules(self):
        "return list of child"
        if not self._module:
            return sys.modules.keys()
        #else:
        #    m=__import__(modules[0])
        
    def __infos__(self,name, module,type_):
        "return information about object"
        
        
            
            
        
        if type_:
            t=getTypeFromString(type_)
            return self.__getInfoFromObjet(t)
        ms=[]    
        if module:
            try:
                modules=module.split(".")
                m=__import__(modules[0])
                ms.append(modules[0])
                modules=modules[1:]
                for subm in modules:
                    if hasattr(m, subm):
                        m=getattr(m,subm)
                    else:
                        ms.append(subm)
                        m=__import__(".".join(ms))
                        
                if name:
                    r=getattr(m,name)
                else:
                    infos=self.__getInfoFromObjet(m)
                    return infos
            except Exception as e:
                return '__$none__'
        else:
            r=eval(name)
        infos=self.__getInfoFromObjet(r)
        
        infos["name"]=name
        infos["module"]=module

        return infos
    
    def __getInfoFromObjet(self,r):
        infos={}
        infos["type"]=str(type(r))
        if self._child:
            infos["list"]=dir(r)
            infos["list"]=self.__getListInfos(infos["list"],r)
        infos["doc"]=r.__doc__
        if type(r)==types.FunctionType:
            infos["param"]=r.__code__.co_varnames
        if type(r)==types.MethodType:
            infos["param"]=r.im_func.func_code.co_varnames
        
        if infos.has_key("param"):
            p=[]
            for i in range(len(infos["param"])):
                param=infos["param"][i]
                if param:
                    p.append(param)
            infos["param"]=p    
        
        return infos
    
    def __getListInfos(self,childs,pyobj):
        ret = {}
        for child in childs:
            obj = {}
            r = getattr(pyobj,child)
            obj["type"] = str(type(r))
            try:
                obj["doc"] = r.__doc__
            except:
                pass
            ret[child] = obj
            
        return ret
    
    
def getTypeFromString(string):
    l=dir(types)
    for t in l:
        #print(str(getattr(types,t)),string,str(t)==string)
        if str(getattr(types,t))==string:
            return t
    return None
    
if __name__ == '__main__':
    Builder().command(sys.argv[1:])
